home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
TextView.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-26
|
22KB
|
984 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "TextView.h"
#include "Class.h"
#include "TextCmd.h"
#include "CmdNo.h"
#include "String.h"
#include "View.h"
#include "Window.h"
#include "Menu.h"
#include "Error.h"
#include "ChangeDialog.h"
#include "Document.h"
#include "RegularExp.h"
#include "ClipBoard.h"
#include "TextFormatter.h"
#include "Env.h"
#include "Data.h"
#include "Math.h"
#include "SortedOList.h"
#include "TextItem.h"
#include "MenuBar.h"
const int cCaretHt = 4,
cCaretWd = 7;
static u_short CaretBits[]= {
# include "images/Caret.image"
};
SmartBitmap CaretImage(Point(cCaretWd, cCaretHt), CaretBits);
static int InputMap[] = {
0, /* 0x00 */
0, /* 0x01 */
0, /* 0x02 */
0, /* 0x03 */
0, /* 0x04 */
0, /* 0x05 */
0, /* 0x06 */
0, /* 0x07 */
0, /* 0x08 */
'\t', /* 0x09 */
'\r', /* 0x0a */
0, /* 0x0b */
0x0c, /* 0x0c */
'\n', /* 0x0d */
0, /* 0x0e */
0, /* 0x0f */
0, /* 0x10 */
0, /* 0x11 */
0, /* 0x12 */
0, /* 0x13 */
0, /* 0x14 */
0, /* 0x15 */
0, /* 0x16 */
0, /* 0x17 */
0, /* 0x18 */
0, /* 0x19 */
0, /* 0x1a */
0, /* 0x1b */
0, /* 0x1c */
0, /* 0x1d */
0, /* 0x1e */
0, /* 0x1f */
};
static int *inputmap= InputMap;
static Ink *caretColor;
void SwapSelPoints(SelPoint &p1, SelPoint &p2)
{
SelPoint tmp;
tmp= p1; p1= p2; p2= tmp;
}
//----- TextView Methods -------------------------------------------------------
NewMetaImpl(TextView, StaticTextView, (TB(updateSelection), TB(inTextSelector),
TB(enabled), TP(stopChars), TP(typing), TP(findChange), TP(scratchText),
T(start.ch), T(start.line), T(start.viewp), T(end.ch), T(end.line),
T(end.viewp)));
TextView::TextView(
EvtHandler *eh, Rectangle r, Text *t,
bool w, TextViewFlags f, Point b,
TViewAlign ta, int id
) : StaticTextView(eh, r, t, w, f, b, ta, id)
{
Init();
}
void TextView::InitNew()
{
View::InitNew();
inTextSelector= FALSE;
}
void TextView::Init()
{
PrivSetSelection(0, 0, FALSE);
typing= 0;
stopChars= 0;
updateSelection= TRUE;
text->AddObserver(this);
scratchText= text->MakeScratchText(0, cMaxBatchedIns);
findChange= 0;
active= TRUE;
inTextSelector= FALSE;
enabled= FALSE;
if (Env::GetValue("TextView.DragAndDrop", TRUE))
SetFlag(eTextViewDragAndDrop);
SetFlag(eVObjKbdFocus);
}
TextView::~TextView()
{
if (text)
text->RemoveObserver(this);
SafeDelete(stopChars);
if (findChange)
findChange->Close();
SafeDelete(findChange);
SafeDelete(scratchText);
}
void TextView::InvalidateSelection()
{
if (AnySelection())
InvalidateRange(start.line, start.viewp, end.line, end.viewp);
}
void TextView::Draw(Rectangle r)
{
if (GrHasColor() && CanShowSelection() && AnySelection())
Invert(start.line, start.viewp, end.line, end.viewp);
StaticTextView::Draw(r);
if (CanShowSelection() && AnySelection()) {
DrawCaret(start.viewp, start.line, On);
if (!GrHasColor())
Invert(start.line, start.viewp, end.line, end.viewp);
}
}
void TextView::DrawCaret(Point p, int line, HighlightState)
{
if (! inTextSelector && AnySelection() && Caret()) {
int bh= BaseHeight(line);
p+= GetInnerOrigin();
if (caretColor == 0) {
if (GrHasColor()) {
caretColor= new_RGBColor(255, 0, 0);
//Env::Bind(caretColor, "TextView.CaretColor");
} else
caretColor= ePatXor;
}
if (LineHeight(line) - bh >= cCaretHt) {
Rectangle r(p.x-cCaretHt, p.y+bh, cCaretWd, cCaretHt);
GrPaintBitMap(r, CaretImage, caretColor);
}
p.x--;
GrPaintLine(caretColor, 0, eDefaultCap, p, Point(p.x, p.y+bh));
}
}
void TextView::SetKeyMap(int *map)
{
inputmap= map;
}
//---- highlight the characters in the given range -----------------------
void TextView::Invert(int from, Point fp, int to, Point tp)
{
if (AnySelection() && !Caret()) {
Rectangle r;
Ink *c= gHighlightColor;
if ((from == to && fp.x > tp.x) || from > to) { // normalize range
SwapRange(from, to);
Swap(fp, tp);
}
if (from == to) {
r= Rectangle(LineToPoint(from)+Point (fp.x,0),
Point(tp.x-fp.x, LineHeight(from)));
GrPaintRect(r+GetInnerOrigin(), c);
return;
}
r= Rectangle(LineToPoint(from)+ Point(fp.x,0),
Point(GetInnerExtent().x-fp.x, LineHeight(from)));
GrPaintRect(r+GetInnerOrigin(), c);
r= Rectangle(LineToPoint(from + 1), Point(GetInnerExtent().x,
LineToPoint(to).y - LineToPoint(from + 1).y));
GrPaintRect(r+GetInnerOrigin(), c);
r= Rectangle(LineToPoint(to), Point(tp.x, LineHeight(to)));
GrPaintRect(r+GetInnerOrigin(), c);
}
}
void TextView::RepairAll()
{
StaticTextView::RepairAll();
if (CanShowSelection())
SetSelection(start.ch, end.ch, FALSE);
}
void TextView::ClearSelection(bool redraw)
{
if (AnySelection()) {
InvalidateSelection();
start.ch= end.ch= -1;
if (redraw)
UpdateEvent();
}
}
void TextView::ShowSelection(bool redraw, bool show)
{
if (enabled != show) {
enabled= show;
InvalidateSelection();
if (redraw)
UpdateEvent();
}
}
bool TextView::KbdFocus(bool in)
{
ShowSelection(FALSE, in);
return TRUE;
}
void TextView::Enable(bool enable, bool redraw)
{
StaticTextView::Enable(enable, redraw);
if (! enable)
HideSelection(redraw);
}
void TextView::PrivSetSelection(SelPoint s, SelPoint e, bool redraw)
{
InvalidateSelection(); // invalidate old selection
start= s;
end= e;
InvalidateSelection(); // invalidate new selection
if (redraw)
UpdateEvent();
Send(GetId(), cPartSelectionChanged, this);
}
void TextView::PrivSetSelection(int s, int e, bool redraw)
{
SelPoint sp, ep;
if (text == 0)
return;
int end= text->End();
sp.ch= Math::Range(0, end, s);
ep.ch= Math::Range(0, end, e);
sp.ch= CharToPoint(sp.ch, &sp.line, &sp.viewp);
if (sp.ch != ep.ch)
ep.ch= CharToPoint(ep.ch, &ep.line, &ep.viewp);
else
ep= sp;
PrivSetSelection(sp, ep, redraw);
}
void TextView::SetSelection(int s, int e, bool redraw)
{
DoneTyping();
PrivSetSelection(s, e, FALSE);
ShowSelection(redraw);
}
void TextView::SelectionAsString(byte *buf, int ma)
{
GetText()->CopyInStr(buf, ma, start.ch, end.ch);
}
Text *TextView::SelectionAsText()
{
return text->Save(start.ch, end.ch);
}
void TextView::SetDragAndDrop(bool on)
{
SetFlag(eTextViewDragAndDrop, on);
}
Rectangle TextView::BoundingRect(int from, int to)
{
Point sp, ep;
int sl, el;
if(from == start.ch) {
sp= start.viewp;
sl= start.line;
} else
CharToPoint(from, &sl, &sp);
if (to == end.ch) {
ep= end.viewp;
el= end.line;
} else
CharToPoint(to, &el, &ep);
Point rp(ep.x+1, ep.y + LineHeight(el));
Rectangle r= NormRect(sp, rp);
r.origin+= GetInnerOrigin();
return r;
}
void TextView::RevealSelection()
{
if (AnySelection()) {
Rectangle r= SelectionRect().Expand(Point(8,0));
RevealRect(r, r.extent);
}
}
Rectangle TextView::SelectionRect()
{
if (AnySelection())
return BoundingRect(start.ch, end.ch);
return gRect0;
}
Command *TextView::DoLeftButtonDownCommand(Point lp, Token t, int clicks)
{
SelPoint oldStart, oldEnd;
TextRangeFP rf= CharacterRange;
oldStart= start;
oldEnd= end;
if (! Enabled())
return View::DoLeftButtonDownCommand(lp, t, clicks);
if (clicks >= 3)
rf= ParagraphRange;
else if (clicks >= 2)
rf= WordRange;
if (t.Flags == eFlgShiftKey)
return new ExtendRangeSelector(this, rf);
if (clicks == 1) {
if (TestFlag(eTextViewDragAndDrop)) {
SelPoint n;
PointToPoint(lp-GetInnerOrigin(), &n.viewp, &n.line, &n.ch);
if (n.ch >= oldStart.ch && n.ch < oldEnd.ch)
return new DragAndDropSelector(this, oldStart.ch, oldEnd.ch, t.Flags == eFlgCntlKey);
}
if (t.Flags == eFlgCntlKey)
return new DragAndDropSelector(this, oldStart.ch, oldEnd.ch, TRUE);
if (t.Flags == (eFlgShiftKey|eFlgCntlKey))
return new QuickPasteSelector(this, oldStart.ch, oldEnd.ch);
}
if (t.Flags == 0)
return new RangeSelector(this, rf);
return View::DoLeftButtonDownCommand(lp, t, clicks);
}
void TextView::SetStopChars(char *stops)
{
strreplace(&stopChars, stops);
}
Command *TextView::DoKeyCommand(int ch, Token)
{
int nDelete= 0;
Token t;
bool newCmd, delSelection; // delete the selection only
if (! Writeable())
return gNoChanges;
GrSetCursor(eCrsNone);
if (ch != '\b' && Iscntrl(ch))
ch= inputmap[ch];
newCmd= (typing == 0); // start new typing sequence?
if (newCmd)
typing= MakeTypingCommand(cTYPEING, "Typing");
delSelection= (newCmd && !Caret());
if (ch != '\b' || delSelection) {
for (;;) {
if (ch != '\b' && ch != '\0') {
typing->AddChar();
scratchText->Append(ch);
}
if (scratchText->Size() == cMaxBatchedIns)
break;
gWindow->ReadEvent(t, 0);
if (t.IsAscii() && (byte)t.Code != '\b'
// do not batch stopChars
&& !(stopChars && strchr(stopChars, (byte)t.Code))
&& ! TestFlag(eTextViewNoBatch)) {
ch= (byte) t.Code;
if (ch != '\b' && Iscntrl(ch))
ch= inputmap[ch];
} else {
if (t.Code != eEvtNone)
gWindow->PushBackEvent(t);
break;
}
}
Paste(scratchText);
scratchText->Empty();
} else {
for (;;) {
typing->DelChar();
nDelete++;
gWindow->ReadEvent(t, 0);
if ((byte) t.Code != '\b') {
gWindow->PushBackEvent(t);
break;
}
}
DelChar(nDelete);
}
RevealSelection();
if (newCmd)
return typing;
return gNoChanges;
}
Command *TextView::DoCursorKeyCommand(EvtCursorDir cd, Token)
{
Point p;
int charNo= 0;
if (! Enabled())
return gNoChanges;
switch (cd) {
case eCrsLeft:
charNo= start.ch-1;
break;
case eCrsRight:
charNo= end.ch+1;
break;
case eCrsUp:
charNo= CursorPos(start.ch, start.line, cd, p);
break;
case eCrsDown:
charNo= CursorPos(end.ch, end.line, cd, p);
break;
}
PrivSetSelection(charNo, charNo);
DoneTyping();
RevealSelection();
return gNoChanges;
}
int TextView::CursorPos(int at, int line, EvtCursorDir d, Point p)
{
int charNo;
Point basePoint, screenPoint;
CharToPoint(at, &line, &screenPoint);
if (d == eCrsDown)
line= Math::Min(nLines-1, line+1);
else
line= Math::Max(0, line-1);
basePoint= LineToPoint(line, TRUE) + Point(screenPoint.x, 0);
PointToPoint(basePoint, &p, &line, &charNo);
return charNo;
}
GrCursor TextView::GetCursor(Point lp)
{
if (TestFlag(eTextViewDragAndDrop)) {
SelPoint n;
PointToPoint(lp-GetInnerOrigin(), &n.viewp, &n.line, &n.ch);
if (n.ch >= start.ch && n.ch < end.ch)
return eCrsBoldArrow;
}
return eCrsIBeam;
}
void TextView::DoneTyping()
{
typing= 0;
text->ResetCurrentCharStyle();
}
void TextView::TypingDeleted(TypingCommand *t)
{
if (t == typing)
typing= 0;
}
TypingCommand *TextView::MakeTypingCommand(int cmdNo, char *name)
{
return new TypingCommand(this, cmdNo, name);
}
bool TextView::DeleteRequest(int,int)
{
return TRUE;
}
void TextView::Cut()
{
if (!Writeable())
return;
if (DeleteRequest(start.ch, end.ch) && AnySelection()) {
updateSelection= FALSE;
text->Cut(start.ch, end.ch);
updateSelection= TRUE;
PrivSetSelection(start.ch, start.ch, FALSE);
}
}
void TextView::Copy(Text *t)
{
text->Copy(t, start.ch, end.ch);
}
void TextView::Paste(Text *t)
{
if (!Writeable())
return;
if ((!Caret() && !DeleteRequest(start.ch, end.ch)) || !AnySelection())
return;
updateSelection= FALSE;
text->Paste(t, start.ch, end.ch);
updateSelection= TRUE;
PrivSetSelection(start.ch+t->End(), start.ch+t->End(), FALSE);
}
Command *TextView::InsertText(Text *t)
{
if (!Writeable())
return gNoChanges;
bool newCmd= (typing == 0); // start new typing sequence?
if (newCmd)
typing= MakeTypingCommand(cTYPEING, "Typing");
typing->AddChar(t->End());
Paste(t);
if (newCmd)
return typing;
return gNoChanges;
}
Command *TextView::InsertString(byte *str, int len)
{
Text *t= text->MakeScratchText(str, len);
Command *cmd= InsertText(t);
SafeDelete(t);
return cmd;
}
void TextView::DelChar(int n)
{
int newStart= Math::Max(0, start.ch-n);
int changedLine= CharToLine(newStart);
if (newStart == start.ch)
return;
if (newStart == 0 && start.ch == 0)
return;
if (DeleteRequest(newStart, start.ch)) {
updateSelection= FALSE;
text->Cut(newStart, start.ch);
updateSelection= TRUE;
PrivSetSelection(newStart, newStart, FALSE);
}
}
Text *TextView::SetText(Text *t, bool scroll)
{
Text *old= text;
SetFlag(eTextViewModified);
ForceRedraw();
old->RemoveObserver(this);
PrivSetSelection(0, 0, FALSE); // reset old selection
text= t;
SafeDelete(scratchText);
scratchText= text->MakeScratchText(0, cMaxBatchedIns);
text->AddObserver(this);
RepairAll();
if (scroll == cRevealTop)
Scroll(cPartScrollAbs, gPoint0, FALSE);
Send(GetId(), cPartReplacedText, 0);
PrivSetSelection(0, 0, FALSE); // set new selection
typing= 0;
return old;
}
void TextView::SetString(byte *str, int len)
{
ForceRedraw();
PrivSetSelection(0, 0, FALSE);
text->ReplaceWithStr(str, len);
RepairAll();
Send(GetId(), cPartReplacedText, 0);
DoneTyping();
PrivSetSelection(0, 0, FALSE);
typing= 0;
}
void TextView::SetReadOnly(bool m)
{
SetFlag(eTextViewReadOnly, m);
}
bool TextView::GetReadOnly()
{
return TestFlag(eTextViewReadOnly);
}
void TextView::DoObserve(int, int part, void *what, Object *op)
{
int d= 0, d1= 0;
if (op == text && part == cPartSenderDied) {
text= 0;
return;
}
if (op == text) {
TextChanges tc= *(TextChanges*)what;
SetFlag(eTextViewModified);
switch (part) {
case eTextChangedRange:
marks->RangeChanged(tc.from, tc.to - tc.from);
Repair(tc.from, tc.to, FALSE);
if (updateSelection && AnySelection())
PrivSetSelection(tc.from, tc.to, TRUE);
break;
case eTextDeleted:
case eTextReplaced:
marks->Replace(tc.from, tc.to, tc.size);
Repair(tc.from, tc.from+tc.size, FALSE);
if (updateSelection && AnySelection()) {
int p= tc.from+tc.size;
PrivSetSelection(p, p, TRUE);
}
break;
}
if (tc.pagination == cPaginationChange)
ForceRedraw();
Send(GetId(), cPartChangedText, this); // notify observers of the textview
}
}
bool TextView::PrintOnWhenObserving(Object *from)
{
return GetText() != from;
}
IStream& TextView::ReadFrom(IStream &s)
{
StaticTextView::ReadFrom(s);
enabled= TRUE;
GetText()->AddObserver(this);
scratchText= text->MakeScratchText(0, cMaxBatchedIns);
return s;
}
void TextView::NormSelection()
{
if (start.ch > end.ch)
SwapSelPoints(start, end);
}
//---- menu related commands -----------------------------------------------
bool TextView::HasSelection()
{
return AnySelection() && !Caret();
}
Command *TextView::PasteData(Data *data)
{
Text *t;
if (t= (Text*) data->AsObject(GetText()->IsA()))
return new PasteCommand(this, t);
return gNoChanges;
}
bool TextView::CanPaste(Data *data)
{
return data->CanConvert(GetText()->IsA());
}
Menu *TextView::MakeMenu(int menuId)
{
int font, size= gSysFont->Size();
GrFont fid= (GrFont)gSysFont->Fid();
char *fontname;
Menu *m;
switch (menuId) {
case cFONTMENU:
m= new Menu(cFONTMENU, "Fonts", FALSE, TRUE, 0, 1, new SortedObjList);
for (font= 0; fontname= gFontManager->IdToName((GrFont)font); font++)
m->AppendItem(fontname, cFIRSTFONT+font);
break;
case cSTYLEMENU:
m= new Menu(cSTYLEMENU, "Styles", FALSE);
m->Append(new MenuButtonItem(cFIRSTFACE+eFacePlain,
new TextItem("Plain", new_Font(fid, size, eFacePlain))));
m->Append(new MenuButtonItem(cFIRSTFACE+eFaceBold,
new TextItem("Bold", new_Font(fid, size, eFaceBold)), "B"));
m->Append(new MenuButtonItem(cFIRSTFACE+eFaceItalic,
new TextItem("Italic", new_Font(fid, size, eFaceItalic)), "I"));
m->Append(new MenuButtonItem(cFIRSTFACE+eFaceUnderline,
new TextItem("Underline", new_Font(fid, size, eFaceUnderline)), "U"));
m->Append(new MenuButtonItem(cFIRSTFACE+eFaceOutline,
new TextItem("Outline", new_Font(fid, size, eFaceOutline))));
m->Append(new MenuButtonItem(cFIRSTFACE+eFaceShadow,
new TextItem("Shadow", new_Font(fid, size, eFaceShadow))));
break;
case cSIZEMENU:
m= new Menu(cSIZEMENU, "Sizes", FALSE);
for (int sz= 9; sz <= 24; sz++)
m->AppendItem(form("%d Points", sz), cFIRSTSIZE+sz);
break;
case cFORMATMENU:
m= new Menu(cFORMATMENU, "Format", FALSE);
m->Append(new MenuButtonItem(cFIRSTADJUST, "Align Left"));
m->Append(new MenuButtonItem(cFIRSTADJUST+1, "Align Right"));
m->Append(new MenuButtonItem(cFIRSTADJUST+2, "Align Center"));
m->Append(new MenuButtonItem(cFIRSTADJUST+3, "Justify"));
m->AppendItems("-", 0);
m->Append(new MenuButtonItem(cFIRSTSPACING+0, "Single Spacing"));
m->Append(new MenuButtonItem(cFIRSTSPACING+18, "1-1/2 Spacing"));
m->Append(new MenuButtonItem(cFIRSTSPACING+24, "Double Spacing"));
break;
}
return m;
}
void TextView::DoSetupMenu(Menu *m)
{
View::DoSetupMenu(m);
switch (m->GetId()) {
case cEDITMENU:
SetupEditMenu(m);
break;
case cSIZEMENU:
SetupSizeMenu(m);
break;
case cFONTMENU:
SetupFontMenu(m);
break;
case cFORMATMENU:
SetupFormatMenu(m);
break;
case cSTYLEMENU:
SetupCharStyleMenu(m);
break;
case cVIEWMENU:
SetupViewMenu(m);
break;
}
}
void TextView::SetupEditMenu(Menu *m)
{
if (!GetReadOnly() && !Caret())
m->EnableItems(cCUT, cIMPORT, 0);
if (AnySelection())
m->EnableItems(cSELECTALL, cFIND, 0);
}
void TextView::SetupSizeMenu(Menu *m)
{
Font *fp= GetCharStyle()->GetFont();
m->CheckItem(cFIRSTSIZE+fp->Size());
}
void TextView::SetupFontMenu(Menu *m)
{
Font *fp= GetCharStyle()->GetFont();
m->CheckItem(gFontManager->NameToId(fp->Name())+cFIRSTFONT);
}
void TextView::SetupViewMenu(Menu *m)
{
m->EnableItem(cSHOWINVIS);
m->CheckItem(cSHOWINVIS, GetShowInvis(), cItemStateManyOf);
}
void TextView::SetupCharStyleMenu(Menu *m)
{
GrFace face= GetCharStyle()->GetFont()->Face();
m->CheckItem(cFIRSTFACE+eFacePlain, face == eFacePlain);
m->CheckItem(cFIRSTFACE+eFaceBold, (face&eFaceBold) == eFaceBold, cItemStateManyOf);
m->CheckItem(cFIRSTFACE+eFaceItalic, (face&eFaceItalic) == eFaceItalic, cItemStateManyOf);
m->CheckItem(cFIRSTFACE+eFaceUnderline, (face&eFaceUnderline) == eFaceUnderline, cItemStateManyOf);
m->CheckItem(cFIRSTFACE+eFaceOutline, (face&eFaceOutline) == eFaceOutline, cItemStateManyOf);
m->CheckItem(cFIRSTFACE+eFaceShadow, (face&eFaceShadow) == eFaceShadow, cItemStateManyOf);
}
void TextView::SetupFormatMenu(Menu *m)
{
int from, to;
GetSelection(&from, &to);
ParaStyle *ps= text->GetParaStyle(from);
m->CheckItem(ps->GetProperty(eTxtPAlign)+cFIRSTADJUST);
m->CheckItem(ps->GetProperty(eTxtPSpacing)+cFIRSTSPACING);
}
Command *SetParaProp(TextView *view, int cmd, TxtParaProp p, int value)
{
ParaDesc pd;
pd.SetProperty(p, value);
return
new ParaStyleCommand(
view,
cmd,
"Change Formatting",
p,
pd
);
}
Command *TextView::DoMenuCommand(int cmd)
{
if (cmd >= cFIRSTSIZE && cmd <= cLASTSIZE)
return new CharStyleCommand(
this,
cmd,
"Change Size",
eTxtPSize,
CharStyleSpec(
eFontDefault,
eFacePlain,
(GrFace)(cmd-cFIRSTSIZE)
)
);
if (cmd >= cFIRSTFONT && cmd <= cLASTFONT)
return new CharStyleCommand(
this,
cmd,
"Change Font",
eTxTPFont,
CharStyleSpec(
(GrFont)(cmd-cFIRSTFONT),
eFacePlain,
0
)
);
if (cmd >= cFIRSTFACE && cmd <= cLASTFACE) {
return new CharStyleCommand(
this,
cmd,
"Change Face",
eTxTPFace,
CharStyleSpec(
eFontDefault,
(GrFace)(cmd-cFIRSTFACE),
0
)
);
}
if (cmd >= cFIRSTSPACING && cmd <= cLASTSPACING) {
ParaDesc pd;
pd.SetProperty(eTxtPSpacing, cmd-cFIRSTSPACING);
return
new ParaStyleCommand(
this,
cmd,
"Change Formatting",
eTxtPSpacing,
pd
);
}
/*
if (cmd >= cFIRSTCOLOR && cmd <= cLASTCOLOR)
return new CharStyleCommand(
this,
cmd,
"Change Color",
eTxtPInk,
CharStyleSpec(
eFontDefault,
eFacePlain,
0,
palette[cmd-cFIRSTCOLOR]
)
);
*/
if (cmd >= cFIRSTADJUST && cmd <= cLASTADJUST)
return SetParaProp(this, cmd, eTxtPAlign, cmd-cFIRSTADJUST);
switch (cmd) {
case cCUT:
case cCOPY:
gClipBoard->SelectionToClipboard(SelectionAsText(), FALSE);
return new CutCopyCommand(this, cmd);
case cSELECTALL:
SelectAll();
break;
case cSHOWINVIS:
ShowInvisibles(!GetShowInvis());
return gNoChanges;
default:
return View::DoMenuCommand(cmd);
}
return gNoChanges;
}
bool TextView::SelectRegExpr(RegularExp *rex, bool dir)
{
int selStart, selEnd, pos, matched;
GetSelection(&selStart, &selEnd);
if (dir == cSearchForward)
pos= GetText()->Search(rex, &matched, selEnd);
else
pos= GetText()->Search(rex, &matched, Math::Max(0, selStart-1), cMaxInt, FALSE);
if (pos != -1) {
PrivSetSelection(pos, pos+matched);
DoneTyping();
return TRUE;
}
return FALSE;
}
void TextView::Home()
{
PrivSetSelection(0, 0);
DoneTyping();
}
void TextView::Bottom()
{
PrivSetSelection(cMaxInt, cMaxInt);
DoneTyping();
}
void TextView::SelectAll(bool redraw)
{
PrivSetSelection(0, text->End(), redraw);
DoneTyping();
}
CharStyle *TextView::GetCharStyle()
{
int from, to;
GetSelection(&from, &to);
if (text->GetCurrentCharStyle())
return text->GetCurrentCharStyle();
else if (text->IsParaStart(from))
from++;
if (from == to)
from--;
return text->GetCharStyle(Math::Max(0, from));
}